package cn.rentaotao.spring.jmx;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableMBeanExport;
import org.springframework.context.annotation.Primary;
import org.springframework.jmx.export.MBeanExporter;
import org.springframework.jmx.export.assembler.InterfaceBasedMBeanInfoAssembler;
import org.springframework.jmx.export.assembler.MBeanInfoAssembler;
import org.springframework.jmx.export.assembler.MethodNameBasedMBeanInfoAssembler;
import org.springframework.jmx.support.MBeanServerFactoryBean;

import java.util.HashMap;
import java.util.Map;

/**
 * @author rtt
 * @date 2022/5/25 14:55
 */
// @Configuration
// @EnableMBeanExport
public class JmxConfig {

    @Bean
    public MBeanExporter mBeanExporter(JmxController jmxController, MBeanInfoAssembler assembler) {
        MBeanExporter mBeanExporter = new MBeanExporter();
        Map<String, Object> beans = new HashMap<>();
        beans.put("jmx:name=JmxController", jmxController);
        mBeanExporter.setBeans(beans);
        mBeanExporter.setAssembler(assembler);
        return mBeanExporter;
    }

    /**
     * 通过名称暴露方法
     * 管理需要暴露的方法
     * 另外还有一个相反的装配起 MethodExclusionMBeanInfoAssembler
     *
     * @return
     */
    @Bean
    @Primary
    public MethodNameBasedMBeanInfoAssembler methodNameBasedMBeanInfoAssembler() {
        MethodNameBasedMBeanInfoAssembler assembler = new MethodNameBasedMBeanInfoAssembler();
        assembler.setManagedMethods("getSize");

        return assembler;
    }

    /**
     * 通过接口指定暴露的方法
     * 目标类可以不是接口的实现类，相当于将方法名归到一个接口上，统一暴露
     *
     * @return
     */
    @Bean
    public InterfaceBasedMBeanInfoAssembler interfaceBasedMBeanInfoAssembler() {
        InterfaceBasedMBeanInfoAssembler assembler = new InterfaceBasedMBeanInfoAssembler();
        assembler.setManagedInterfaces(JmxService.class);

        return assembler;
    }

    @Bean
    public MBeanServerFactoryBean mBeanServer() {
        return new MBeanServerFactoryBean();
    }
}
